package com.tbit.uqbike.center.service.impl;

import com.tbit.uqbike.center.constant.MachineStatusConstant;
import com.tbit.uqbike.center.constant.SysConstant;
import com.tbit.uqbike.center.constant.SystemConstant;
import com.tbit.uqbike.center.constant.SystemData;
import com.tbit.uqbike.center.dao.core.MachineStatusDao;
import com.tbit.uqbike.center.dao.ter.TerBatteryDao;
import com.tbit.uqbike.center.dao.ter.TerPositionDao;
import com.tbit.uqbike.center.pojo.*;
import com.tbit.uqbike.center.service.*;
import com.tbit.uqbike.center.util.DateTimeUtil;
import com.tbit.uqbike.center.util.LogUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("machineStatusService")
public class MachineStatusServiceImpl implements MachineStatusService {
    private static final Logger log = LoggerFactory.getLogger(MachineStatusServiceImpl.class);
    @Autowired
    private TerPositionDao terPositionDao;
    @Autowired
    private TerBatteryDao terBatteryDao;
    @Autowired
    private MachineStatusDao machineStatusDao;
    @Autowired
    private MachineService machineService;
    @Autowired
    private BatteryModelDetailService batteryModelDetailService;
    @Autowired
    private QuartzJobService quartzJobService;
    @Autowired
    private BatteryBmsService batteryBmsService;

    @Override
    public void initMachineData() {
        try {
            if (SystemData.machineStatusMap.isEmpty()) {
                synchronized (this) {
                    // 双检锁避免重复初始化
                    if (!SystemData.machineStatusMap.isEmpty()){
                        return ;
                    }
                    /**同步时间*/
                    SystemData.lastSynTime = System.currentTimeMillis();

                    /**最大设备id*/
                    Integer maxMachineId = machineService.getMaxMachineId();
                    SystemData.maxMachineId = maxMachineId;

                    /**加载所有设备信息*/
                    List<MachineBase> machineBases = machineService.getAllMachineBase();
                    for (MachineBase machineBase : machineBases) {
                        SystemData.machineNOMachineIdMap.put(machineBase.getMachineNO(), machineBase.getMachineId());
                        SystemData.machineIdAccountIdMap.put(machineBase.getMachineId(), machineBase.getAccountId());
                        SystemData.machineIdMachineMap.put(machineBase.getMachineId(), machineBase);
                    }


                    /**加载所有最后位置数据*/
                    Map<String, TerPosition> terPositionMap = new HashMap<String, TerPosition>();
                    List<TerPosition> terPositions = terPositionDao.getAll();
                    for (TerPosition terPosition : terPositions) {
                        terPositionMap.put(terPosition.getMachineNO(), terPosition);
                    }

                    /**加载所有最后电量数据*/
                    Map<String, TerBattery> terBatteryMap = new HashMap<String, TerBattery>();
                    List<TerBattery> terBatterys = terBatteryDao.getAll();
                    for (TerBattery terBattery : terBatterys) {
                        terBatteryMap.put(terBattery.getMachineNO(), terBattery);
                    }

                    for (MachineBase machineBase : machineBases) {
                        String machineNO = machineBase.getMachineNO();
                        TerPosition terPosition = terPositionMap.get(machineNO);
                        TerBattery terBattery = terBatteryMap.get(machineNO);

                        MachineStatus machineStatus = new MachineStatus();

                        machineStatus.setMachineId(machineBase.getMachineId());
                        machineStatus.setMachineNO(machineNO);
                        if (terPosition != null) {
                            machineStatus.setPosDt(terPosition.getDt());
                            machineStatus.setLon(terPosition.getLon());
                            machineStatus.setLat(terPosition.getLat());
                            machineStatus.setTerStatus(terPosition.getCarStatus());
                        }

                        if (terBattery != null) {
                            machineStatus.setBatDt(terBattery.getDt());
                            machineStatus.setSoc(terBattery.getSoc());
                            machineStatus.setBatteryEI(terBattery.getBatteryEI());
                            machineStatus.setBatteryEU(terBattery.getBatteryEU());
                        }

                        SystemData.machineStatusMap.put(machineStatus.getMachineId(), machineStatus);
                    }

                    LogUtil.info("加载位置电量数据[" + SystemData.machineStatusMap.size() + "]");
                }
            }
        }catch (Exception e){
            log.error("加载位置电量数据异常",e);
        }

    }

    @Override
    public void updatePosition(TerPosition terPosition) {
        /**加载设备数据*/
        initMachineData();
        /**查询设备id*/
        Integer machineId = SystemData.machineNOMachineIdMap.get(terPosition.getMachineNO());

        if (machineId != null) {
            MachineStatus machineStatus = SystemData.machineStatusMap.get(machineId);
            if (machineStatus != null) {
                /**过滤非GPS定位 3.7新增高精度定位类型为6、手动定位为-1*/
                if (terPosition.getPointType() == 1 || terPosition.getPointType() == 6 || terPosition.getPointType() == -1) {
                    long pos_timestamp = Long.parseLong(terPosition.getDt());
                    long time_gap = (System.currentTimeMillis() - pos_timestamp) / 1000;
                    if (time_gap > 60 * 60) {
                        machineStatus.setPosDt(DateTimeUtil.getNowTime());
                    } else {
                        /**更新最后位置*/
                        machineStatus.setPosDt(DateTimeUtil.getDateTimeByGL(pos_timestamp));
                    }
                    //machineStatus.setPosDt(DateTimeUtil.getNowTime());
                    machineStatus.setLon(terPosition.getLon());
                    machineStatus.setLat(terPosition.getLat());
                    machineStatus.setTerStatus(terPosition.getCarStatus());
                    machineStatus.setPosType(getType(terPosition.getPointType()));
                } else {
                    machineStatus.setTerStatus(terPosition.getCarStatus());
                }
            }
        }

    }

    /**
     * 定位转化
     *
     * @param type
     * @return
     */
    public Integer getType(Integer type) {
        if (type.equals(MachineStatusConstant.POINTTYPE_GPS)) {
            return MachineStatusConstant.BUSINESS_POINTTYPE_GPS;
        } else if (type.equals(MachineStatusConstant.POINTTYPE_HIGH_PRECISION)) {
            return MachineStatusConstant.BUSINESS_POINTTYPE_HIGH_PRECISION;
        } else if (type.equals(MachineStatusConstant.POINTTYPE_MANUAL)) {
            return MachineStatusConstant.BUSINESS_POINTTYPE_MANUAL;
        } else {
            return type;
        }
    }

    @Override
    public void updateBattery(TerBattery terBattery) {
        /**加载设备数据*/
        initMachineData();
        /**触发电池方案*/
        if (SystemData.batteryModelListMap.size() == 0) {
            quartzJobService.synBatteryData();
        }
        /**查询设备id*/
        Integer machineId = SystemData.machineNOMachineIdMap.get(terBattery.getMachineNO());

        if (machineId != null) {
            /**标注需要更新电量设备*/
            SystemData.needUpdateBatteryMap.put(machineId, machineId);

            MachineStatus mahcineStatus = SystemData.machineStatusMap.get(machineId);
            if (mahcineStatus != null) {

                long pos_timestamp = Long.parseLong(terBattery.getDt());
                long time_gap = (System.currentTimeMillis() - pos_timestamp) / 1000;

                if (time_gap > 60 * 60) {
                    mahcineStatus.setBatDt(DateTimeUtil.getNowTime());
                } else {
                    /**更新最后位置*/
                    mahcineStatus.setBatDt(DateTimeUtil.getDateTimeByGL(pos_timestamp));
                }
                /**更新时间直接取收到时间*/
                mahcineStatus.setBatDt(DateTimeUtil.getNowTime());
                mahcineStatus.setBatteryEI(terBattery.getBatteryEI());
                mahcineStatus.setBatteryEU(terBattery.getBatteryEU());
                if (terBattery.getProMap() != null) {
                    mahcineStatus.setTerStatus(
                            terBattery.getProMap().get("terStatus") == null ? mahcineStatus.getTerStatus()
                                    : Integer.valueOf(terBattery.getProMap().get("terStatus").toString()));
                }
                //LogUtil.info(terBattery.getMachineNO()+"->"+terBattery.getBatteryEU());
                /**支持BMS的中控*/
                if (terBattery.getSoc() != null) {
                    /**BMS故障值会大于100*/
                    if (terBattery.getSoc() > 0 && terBattery.getSoc() <= 100) {
                        mahcineStatus.setSoc(terBattery.getSoc());
                        mahcineStatus.setBmsErr(0);
                    } else {
                        /**设置BMS故障*/
                        mahcineStatus.setBmsErr(1);

                        /**BMS为0并且电压为0，更新BMS电量*/
                        if (terBattery.getSoc() == 0 && terBattery.getBatteryRelativelyRemaining() == 0) {
                            Integer batteryModelId = SystemData.machineIdBatteryModelIdMap.get(machineId);
                            if (batteryModelId != null) {
                                BatteryModel bm = SystemData.batteryModelMap.get(batteryModelId);
                                if (bm != null && bm.getBatteryType() == 1) {
                                    boolean isEU = true;
                                    /**先看电压方案，如果电压方案大于50认为是有电*/
                                    List<BatteryModelDetail> batteryModelDetails = SystemData.batteryModelListMap.get(batteryModelId);
                                    if (batteryModelDetails != null && batteryModelDetails.size() > 0 && mahcineStatus.getBatteryEU() != null) {
                                        Float vol = mahcineStatus.getBatteryEU() / 1000F;
                                        for (BatteryModelDetail batteryModelDetail : batteryModelDetails) {
                                            if (batteryModelDetail.getMinVol() <= vol && vol <= batteryModelDetail.getMaxVol() && batteryModelDetail.getBatteryPer() >= SystemConstant.batteryeu) {
                                                /**更新电量*/
                                                mahcineStatus.setSocPercent(batteryModelDetail.getBatteryPer());
                                                mahcineStatus.setSurplusMileage(batteryModelDetail.getMilage());
                                                isEU = false;
                                                break;
                                            }
                                        }
                                    }
                                    if (isEU) {
                                        mahcineStatus.setSoc(terBattery.getSoc());
                                        mahcineStatus.setBmsErr(0);
                                    }
                                }
                            }

                        }
                    }
                }

                /**外电断开实时更新电量(电压小于10V)*/
                if (mahcineStatus.getBatteryEU() != null && mahcineStatus.getBatteryEU() < 10000) {
                    batteryModelDetailService.updateMachineBattery(machineId);
                }
                /**云bms逻辑处理*/
//				LinkedList<MachineBattery> machineBatterys= SystemData.machineBatteryMap.get(mahcineStatus.getMachineId());
//				if(machineBatterys!=null&&!machineBatterys.isEmpty()) {
//					synchronized (machineBatterys) {
//						MachineBattery machineBattery = machineBatterys.getFirst();
//						/**多少秒内*/
//						Integer time = Integer.valueOf(SystemConstant.time);
//						/**电压变化多少毫伏*/
//						Integer battery = Integer.valueOf(SystemConstant.battery);
//						/**指定秒数内电压大于一定值，就会置成bms异常*/
//						if (DateTimeUtil.getTimeDF(machineBattery.getBatteryDt(), mahcineStatus.getBatDt())
//								>= time) {
//							/**电压变化大于一定值*/
//							if (machineBattery.getBattery() - mahcineStatus.getBatteryEU() >= battery) {
//								String batteryNO = SystemData.machineIdBatteryMap.get(mahcineStatus.getMachineId());
//								MachineBase machine = SystemData.machineIdMachineMap.get(mahcineStatus.getMachineId());
//								if (batteryNO != null && machine != null) {
//									Integer count = batteryBmsService.getExist(1, machine.getAccountId(), batteryNO);
//									if (count == 0) {
//										Integer accountId = batteryBmsService.getAccountId(mahcineStatus.getMachineId());
//										/**异常类型 1为电压大幅较低导致异常*/
//										batteryBmsService.edit(1, machine.getAccountId(), batteryNO);
//										/**添加异常*/
//										BmsAbnormal bmsAbnormal = new BmsAbnormal();
//										bmsAbnormal.setAccountId(accountId);
//										bmsAbnormal.setAbnormalType(1);
//										bmsAbnormal.setAdAccountId(machine.getAccountId());
//										bmsAbnormal.setBatteryNO(batteryNO);
//										bmsAbnormal.setMachineNo(machine.getMachineNO());
//										bmsAbnormal.setUserCode(machine.getUserCode());
//										bmsAbnormal.setAbnormalRemark("电压大幅降低,系统自动添加");
//										batteryBmsService.add(bmsAbnormal);
//									}
//								}
//							}
//
//						}
//						machineBatterys.addLast(
//								new MachineBattery(mahcineStatus.getMachineId(), mahcineStatus.getBatDt(),
//										mahcineStatus.getBatteryEU()));
//						if (machineBatterys.size() > 20) {
//							machineBatterys.removeFirst();
//						}
//					}
//				}else{
//					machineBatterys = new LinkedList<>();
//					MachineBattery machineBattery = new MachineBattery(mahcineStatus.getMachineId(),
//							mahcineStatus.getBatDt(), mahcineStatus.getBatteryEU());
//					machineBatterys.add(machineBattery);
//					SystemData.machineBatteryMap.put(mahcineStatus.getMachineId(), machineBatterys);
//				}
            }

        }
    }


    @Override
    public void updateLithiumBattery(TerBattery terBattery) {
        /**加载设备数据*/
        initMachineData();
        /**触发电池方案*/
        if (SystemData.batteryModelListMap.size() == 0) {
            quartzJobService.synBatteryData();
        }
        log.info("更新氢燃料电池信息{}", terBattery);
        /**查询设备id*/
        Integer machineId = SystemData.machineNOMachineIdMap.get(terBattery.getMachineNO());
        if (machineId != null) {
            TerAttrEx terAttrEx = new TerAttrEx();
            terAttrEx.setDt(DateTimeUtil.getDateTimeByGL(Long.parseLong(terBattery.getDt())));
            terAttrEx.setMachineNO(terBattery.getMachineNO());
            terAttrEx.setName(SysConstant.Type_LI_tLSOC);
            // 氢能源电池有上报soc直接用soc设置，可能会出现大于100
            if(terBattery.getSoc() != null){
                if(terBattery.getSoc()>= 0 && terBattery.getSoc() <= 100){
                    terAttrEx.setValue(terBattery.getSoc());
                } else{
                    terAttrEx.setValue(-1);
                }
            } else {
                Integer batteryModelId = SystemData.machineIdSecondaryBatteryModelIdMap.get(machineId);
                List<BatteryModelDetail> batteryModelDetails = SystemData.batteryModelListMap.get(batteryModelId);
                if (batteryModelDetails != null && batteryModelDetails.size() > 0) {
                    Float vol = terBattery.getBatteryEU() / 1000F;
                    for (BatteryModelDetail batteryModelDetail : batteryModelDetails) {
                        if (batteryModelDetail.getMinVol() <= vol && vol <= batteryModelDetail.getMaxVol()) {
                            /**更新电量*/
                            terAttrEx.setValue(batteryModelDetail.getBatteryPer());
                            break;
                        }
                    }
                }
            }
            SystemData.lithiumMap.put(terBattery.getMachineNO(), terAttrEx);
        }
    }

    @Override
    public List<MachineStatus> getByMachineIds(List<Integer> machineIds) {
        List<MachineStatus> machineStatuses = new ArrayList<MachineStatus>();

        for (Integer machineId : machineIds) {
            MachineStatus machineStatus = SystemData.machineStatusMap.get(machineId);
            if (machineStatus == null) {
                /**查询设备信息*/
                MachineBase machineBase = machineService.getByMachineId(machineId);
                if (machineBase != null) {
                    /**加载数据*/
                    TerPosition terPosition = terPositionDao.getByMachineNO(machineBase.getMachineNO());
                    TerBattery terBattery = terBatteryDao.getByMachineNO(machineBase.getMachineNO());

                    machineStatus = new MachineStatus();

                    machineStatus.setMachineId(machineBase.getMachineId());
                    machineStatus.setMachineNO(machineBase.getMachineNO());

                    if (terPosition != null) {
                        machineStatus.setPosDt(terPosition.getDt());
                        machineStatus.setLon(terPosition.getLon());
                        machineStatus.setLat(terPosition.getLat());
                        machineStatus.setTerStatus(terPosition.getCarStatus());
                    }

                    if (terBattery != null) {
                        machineStatus.setBatDt(terBattery.getDt());
                        machineStatus.setSoc(terBattery.getSoc());
                        machineStatus.setBatteryEI(terBattery.getBatteryEI());
                        machineStatus.setBatteryEU(terBattery.getBatteryEU());
                    }

                    /**添加到内存*/
                    SystemData.machineNOMachineIdMap.put(machineBase.getMachineNO(), machineBase.getMachineId());
                    SystemData.machineStatusMap.put(machineStatus.getMachineId(), machineStatus);
                    SystemData.machineIdMachineMap.put(machineBase.getMachineId(), machineBase);
                    machineStatuses.add(machineStatus);
                }
            } else {
                machineStatuses.add(machineStatus);
            }
        }

        return machineStatuses;
    }

    @Override
    public synchronized void updateBatch(List<MachineStatus> machineStatuses) {
		/*List<Integer> machineIds =  new ArrayList<>();
		machineIds.addAll(machineStatuses.stream().map(MachineStatus::getMachineId).collect(Collectors.toList()));
		List<Integer> exitIds = machineStatusDao.getByMachineId(machineIds);
		*//**新增的设备*//*
		List<MachineStatus> addMachineIds = new ArrayList<>();
		*//**修改的设备*//*
		List<MachineStatus> editMachines= new ArrayList<>();
		for (MachineStatus machineStatus:machineStatuses) {
			if(exitIds.contains(machineStatus.getMachineId())){
				editMachines.add(machineStatus);
			}else{
				addMachineIds.add(machineStatus);
			}
		}
		*//**新增id*//*
		if(addMachineIds.size()>0){
			machineStatusDao.addBatch(addMachineIds);
		}
		if(editMachines.size()>0){
			for (MachineStatus m:editMachines) {
				machineStatusDao.edit(m);
			}
		}
*/
        machineStatusDao.updateBatchV2(machineStatuses);

        //machineStatusDao.updateBatch(machineStatuses);
    }


    @Override
    public void loadPosition(Integer machineId) {
        MachineStatus machineStatus = SystemData.machineStatusMap.get(machineId);

        if (machineStatus != null) {
            TerPosition terPosition = terPositionDao.getByMachineNO(machineStatus.getMachineNO());

            if (terPosition != null) {
                machineStatus.setLon(terPosition.getLon());
                machineStatus.setLat(terPosition.getLat());
                machineStatus.setPosDt(terPosition.getDt());
                machineStatus.setTerStatus(terPosition.getCarStatus());
            } else {
                LogUtil.warn("数据库无位置信息[" + machineId + "]");
            }
        }
        LogUtil.info("数据库加载位置信息[" + machineId + "]");
    }

    @Override
    public void loadMachineStatus(Integer machineId) {
        /**查询设备信息*/
        MachineBase machineBase = machineService.getByMachineId(machineId);
        if (machineBase != null) {
            /**加载数据*/
            TerPosition terPosition = terPositionDao.getByMachineNO(machineBase.getMachineNO());
            TerBattery terBattery = terBatteryDao.getByMachineNO(machineBase.getMachineNO());

            MachineStatus machineStatus = new MachineStatus();

            machineStatus.setMachineId(machineBase.getMachineId());
            machineStatus.setMachineNO(machineBase.getMachineNO());

            if (terPosition != null) {
                machineStatus.setPosDt(terPosition.getDt());
                machineStatus.setLon(terPosition.getLon());
                machineStatus.setLat(terPosition.getLat());
                machineStatus.setTerStatus(terPosition.getCarStatus());
            }

            if (terBattery != null) {
                machineStatus.setBatDt(terBattery.getDt());
                machineStatus.setSoc(terBattery.getSoc());
                machineStatus.setBatteryEI(terBattery.getBatteryEI());
                machineStatus.setBatteryEU(terBattery.getBatteryEU());
            }

            /**添加到内存*/
            SystemData.machineNOMachineIdMap.put(machineBase.getMachineNO(), machineBase.getMachineId());
            SystemData.machineStatusMap.put(machineStatus.getMachineId(), machineStatus);
            SystemData.machineIdMachineMap.put(machineBase.getMachineId(), machineBase);
        }

    }

}